//
//  MLXTakePhotoManager.m
//  MLX
//
//  Created by SY on 2018/10/7.
//  Copyright © 2018年 SY. All rights reserved.
//

#import "MLXTakePhotoManager.h"
#import "MLXToolUtils+MLXFile.h"
#import "MLXPhotoModel.h"
#import <Photos/Photos.h>
#import <MobileCoreServices/MobileCoreServices.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import <TZImagePickerController/TZImagePickerController.h>

#define ORIGINAL_MAX_WIDTH 640.0f

static MLXTakePhotoManager *takePhotoManager = nil;
typedef void(^MLXTakePhotoblock)(NSArray *photos,NSArray *assets,BOOL isVideo);

@interface MLXTakePhotoManager ()<UIImagePickerControllerDelegate,UINavigationControllerDelegate,TZImagePickerControllerDelegate>
@property(nonatomic,copy) MLXTakePhotoblock takePhotoblock;

@end

@implementation MLXTakePhotoManager
+ (instancetype)shareManager{
    takePhotoManager = [[MLXTakePhotoManager alloc]init];
    return takePhotoManager;
}
- (void)takePhotoPhotoOfController:(UIViewController *)controller currentImgCount:(NSInteger)imgCount maxImgCount:(NSInteger)maxImgCount allowPickingVideo:(BOOL)allowPickingVideo allowPickingImage:(BOOL)allowPickingImage  selectedAssets:(NSArray *)selectedAssets photos:(void (^)(NSArray * photos,NSArray *assets,BOOL isVideo))takePhotoblock{
    self.takePhotoblock = takePhotoblock;
    UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"添加媒体资源" message:nil preferredStyle:UIAlertControllerStyleActionSheet];
    UIAlertAction *takePhoto = [UIAlertAction actionWithTitle:@"拍摄" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
            UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
            imagePicker.modalPresentationStyle= UIModalPresentationOverFullScreen;
            imagePicker.delegate = self;
            [imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
//            imagePicker.mediaTypes = @[(NSString *)kUTTypeImage];
            imagePicker.videoMaximumDuration = 10.0f;
            [controller presentViewController:imagePicker animated:YES completion:nil];
        }else{
            // 无权限 做一个友好的提示
            UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"无法使用相机" message:@"请在iPhone的""设置-隐私-相机""中允许访问相机" preferredStyle:UIAlertControllerStyleAlert];
            UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
            UIAlertAction *set = [UIAlertAction actionWithTitle:@"设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0f) {
                    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
                }
            }];
            [alert addAction:cancel];
            [alert addAction:set];
            [controller presentViewController:alert animated:YES completion:nil];
        }
    }];
    UIAlertAction *selectPhoto = [UIAlertAction actionWithTitle:@"照片" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        TZImagePickerController *imagePickerVc = [[TZImagePickerController alloc] initWithMaxImagesCount: maxImgCount - imgCount delegate:self];
        imagePickerVc.allowPickingVideo = allowPickingVideo;
        imagePickerVc.allowPickingImage = allowPickingImage;
        imagePickerVc.allowTakePicture = NO;
        imagePickerVc.timeout = CGFLOAT_MAX;
        if(selectedAssets) imagePickerVc.selectedAssets = [selectedAssets mutableCopy];
        imagePickerVc.naviBgColor = kMainColor;
        imagePickerVc.naviTitleFont = [UIFont systemFontOfSize:20];
        imagePickerVc.naviTitleColor = [UIColor whiteColor];
        imagePickerVc.barItemTextColor = [UIColor whiteColor];
        imagePickerVc.naviTitleColor = [UIColor whiteColor];
        
        [controller presentViewController:imagePickerVc animated:YES completion:nil];
        
        
    }];
    UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:takePhoto];
    [alert addAction:selectPhoto];
    [alert addAction:cancel];
    [controller presentViewController:alert animated:YES completion:nil];
    
}
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingPhotos:(NSArray *)photos sourceAssets:(NSArray *)assets isSelectOriginalPhoto:(BOOL)isSelectOriginalPhoto{
    if (assets.count == 0) return;
    NSMutableArray *imageArr = [NSMutableArray arrayWithCapacity:photos.count];
    for (UIImage *asset in photos) {
        MLXPhotoModel *model = [MLXPhotoModel new];
        model.photoModelType = MLXPhotoModelTypeLocationPhoto;
        NSData *data = UIImagePNGRepresentation(asset);
        model.md5Str = [data MD5];
        model.locationImage = [asset drawImageWidth:MLX_SCALEWIDTH(200)];
        model.photoW = asset.size.width;
        model.photoH = asset.size.height;
        [imageArr addObject:model];
    }
    !self.takePhotoblock ?: self.takePhotoblock(imageArr,assets, NO);
    [picker dismissViewControllerAnimated:YES completion:^{
    }];
}
// 如果用户选择了一个视频，下面的handle会被执行
// 如果系统版本大于iOS8，asset是PHAsset类的对象，否则是ALAsset类的对象
- (void)imagePickerController:(TZImagePickerController *)picker didFinishPickingVideo:(UIImage *)coverImage sourceAssets:(id)asset {
    void (^complete)(AVURLAsset * _Nonnull videoAsset) = ^(AVURLAsset * _Nonnull videoAsset){
        dispatch_async(dispatch_get_main_queue(), ^{
            //视频不存在
            if (!videoAsset.URL)  return;
            [MLXToolUtils compressSlectVideoAssetForSend:videoAsset
                                          cancelCallback:^{
                                          }
                                            failCallback:^{
                                            }
                                         successCallback:^(NSString *mp4Path) {
                                             CGFloat duration = round([MLXToolUtils getVideoLength:mp4Path]);
                                             MLXPhotoModel *model = [MLXPhotoModel new];
                                             NSData *data = [NSData dataWithContentsOfFile:mp4Path];
                                             model.md5Str = [data MD5];
                                             model.photoModelType = MLXPhotoModelTypeLocationVideo;
                                             model.duration = duration;
                                             model.videoLocationUrl = mp4Path;
                                             model.videoURL = [NSURL fileURLWithPath:mp4Path];
                                             model.locationFistImageImage = coverImage;
                                             CGSize thumbnailSize = [MLXToolUtils getVideoSize:mp4Path];
                                             model.photoW = thumbnailSize.width;
                                             model.photoH = thumbnailSize.height;
                                             !self.takePhotoblock ?: self.takePhotoblock(@[model],@[asset], YES);
                                             [picker dismissViewControllerAnimated:YES completion:nil];
                                         }];
            
        });
        
    };
    
    if ([asset isKindOfClass:[PHAsset class]]) {
        PHVideoRequestOptions* options = [[PHVideoRequestOptions alloc] init];
        options.version = PHVideoRequestOptionsVersionOriginal;
        options.deliveryMode = PHVideoRequestOptionsDeliveryModeAutomatic;
        options.networkAccessAllowed = NO;
        [[PHImageManager defaultManager] requestAVAssetForVideo:asset options:options resultHandler:^(AVAsset* avasset, AVAudioMix* audioMix, NSDictionary* info){
            AVURLAsset *videoAsset = (AVURLAsset*)avasset;
            complete(videoAsset);
        }];
    }else if ([asset isKindOfClass:[ALAsset class]]) {
        NSURL *videoURL = [asset valueForProperty:ALAssetPropertyAssetURL];
        AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
        complete(videoAsset);
    }
    
}
- (void)imagePickerControllerDidCancel:(TZImagePickerController *)picker{
    [picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissViewControllerAnimated:YES completion:^() {
        //通过UIImagePickerControllerMediaType判断返回的是照片还是视频
        //如果返回的type等于kUTTypeImage，代表返回的是照片,并且需要判断当前相机使用的sourcetype是拍照还是相册
        NSString* type = [info objectForKey:UIImagePickerControllerMediaType];
        UIImage* portraitImg = [info objectForKey:UIImagePickerControllerOriginalImage];
        if ([type isEqualToString:(NSString*)kUTTypeImage]) {
            //获取照片的原图
            portraitImg = [self imageByScalingToMaxSize:portraitImg];
                NSData *imageData;
                for (int a = 10  ; a  > 1; a = a - 2) {
                    imageData = UIImageJPEGRepresentation(portraitImg, a/10.0f);
                    if(imageData.length/1024.0f < 200){
                        break;
                    }
                }
                UIImage *image = [UIImage imageWithData:imageData];
                MLXPhotoModel *model = [MLXPhotoModel new];
                model.photoModelType = MLXPhotoModelTypeLocationPhoto;
                model.locationImage = image;
                model.photoW = image.size.width;
                model.photoH = image.size.height;
                !self.takePhotoblock ?: self.takePhotoblock(@[model],@[],YES);
            
        }else{
            void (^complete)(AVURLAsset * _Nonnull videoAsset) = ^(AVURLAsset * _Nonnull videoAsset){
                dispatch_async(dispatch_get_main_queue(), ^{
                    //视频不存在
                    if (!videoAsset.URL)  return;
                    [MLXToolUtils compressSlectVideoAssetForSend:videoAsset
                                                  cancelCallback:^{
                                                  }
                                                    failCallback:^{
                                                    }
                                                 successCallback:^(NSString *mp4Path) {
                                                     CGFloat duration = round([MLXToolUtils getVideoLength:mp4Path]);
                                                     MLXPhotoModel *model = [MLXPhotoModel new];
                                                     NSData *data = [NSData dataWithContentsOfFile:mp4Path];
                                                     UIImage *coverImage = [self frameImageFromVideoURL:[NSURL fileURLWithPath:mp4Path]];
                                                     model.md5Str = [data MD5];
                                                     model.photoModelType = MLXPhotoModelTypeLocationVideo;
                                                     model.duration = duration;
                                                     model.videoLocationUrl = mp4Path;
                                                     model.videoURL = [NSURL fileURLWithPath:mp4Path];
                                                     model.locationFistImageImage = coverImage;
                                                     CGSize thumbnailSize = [MLXToolUtils getVideoSize:mp4Path];
                                                     model.photoW = thumbnailSize.width;
                                                     model.photoH = thumbnailSize.height;
                                                     !self.takePhotoblock ?: self.takePhotoblock(@[model],@[], YES);
                                                 }];
                    
                });
            };
            
            NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
            AVURLAsset *videoAsset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
            complete(videoAsset);
        }
     
    }];
}
#pragma mark image scale utility
- (UIImage *)imageByScalingToMaxSize:(UIImage *)sourceImage {
    if (sourceImage.size.width < ORIGINAL_MAX_WIDTH) return sourceImage;
    CGFloat btWidth = 0.0f;
    CGFloat btHeight = 0.0f;
    if (sourceImage.size.width > sourceImage.size.height) {
        btHeight = ORIGINAL_MAX_WIDTH;
        btWidth = sourceImage.size.width * (ORIGINAL_MAX_WIDTH / sourceImage.size.height);
    } else {
        btWidth = ORIGINAL_MAX_WIDTH;
        btHeight = sourceImage.size.height * (ORIGINAL_MAX_WIDTH / sourceImage.size.width);
    }
    CGSize targetSize = CGSizeMake(btWidth, btHeight);
    return [self imageByScalingAndCroppingForSourceImage:sourceImage targetSize:targetSize];
}
- (UIImage *)imageByScalingAndCroppingForSourceImage:(UIImage *)sourceImage targetSize:(CGSize)targetSize {
    UIImage *newImage = nil;
    CGSize imageSize = sourceImage.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;
    CGFloat targetWidth = targetSize.width;
    CGFloat targetHeight = targetSize.height;
    CGFloat scaleFactor = 0.0;
    CGFloat scaledWidth = targetWidth;
    CGFloat scaledHeight = targetHeight;
    CGPoint thumbnailPoint = CGPointMake(0.0,0.0);
    if (CGSizeEqualToSize(imageSize, targetSize) == NO)
    {
        CGFloat widthFactor = targetWidth / width;
        CGFloat heightFactor = targetHeight / height;
        
        if (widthFactor > heightFactor)
            scaleFactor = widthFactor; // scale to fit height
        else
            scaleFactor = heightFactor; // scale to fit width
        scaledWidth  = width * scaleFactor;
        scaledHeight = height * scaleFactor;
        
        // center the image
        if (widthFactor > heightFactor)
        {
            thumbnailPoint.y = (targetHeight - scaledHeight) * 0.5;
        }
        else
            if (widthFactor < heightFactor)
            {
                thumbnailPoint.x = (targetWidth - scaledWidth) * 0.5;
            }
    }
    UIGraphicsBeginImageContext(targetSize); // this will crop
    CGRect thumbnailRect = CGRectZero;
    thumbnailRect.origin = thumbnailPoint;
    thumbnailRect.size.width  = scaledWidth;
    thumbnailRect.size.height = scaledHeight;
    
    [sourceImage drawInRect:thumbnailRect];
    
    newImage = UIGraphicsGetImageFromCurrentImageContext();
    if(newImage == nil) NSLog(@"could not scale image");
    
    //pop the context to get back to the default
    UIGraphicsEndImageContext();
    return newImage;
}
- (UIImage *)frameImageFromVideoURL:(NSURL *)videoURL {
    
    UIImage *image = nil;
    
    AVAsset *asset = [AVAsset assetWithURL:videoURL];
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    imageGenerator.appliesPreferredTrackTransform = YES;
    Float64 duration = CMTimeGetSeconds([asset duration]);
    // 取某个帧的时间，参数一表示哪个时间（秒），参数二表示每秒多少帧
    // 通常来说，600是一个常用的公共参数，苹果有说明:
    CMTime midpoint = CMTimeMakeWithSeconds(duration / 2.0, 600);
    
    NSError *error = nil;
    CMTime actualTime;
    
    CGImageRef centerFrameImage = [imageGenerator copyCGImageAtTime:midpoint
                                                         actualTime:&actualTime
                                                              error:&error];
    if (centerFrameImage != NULL) {
        image = [[UIImage alloc] initWithCGImage:centerFrameImage];
        CGImageRelease(centerFrameImage);
    }
    return image;
}
@end
